#include "pch.h"
#include "Program.h"
#include <algorithm>

Program::Program()
{
	Id = glCreateProgram();
}


Program::~Program()
{
	UnUse();
	glDeleteProgram(Id);
}

void Program::UnUse()
{
	glUseProgram(0);
}

void Program::Unbind()
{
	UnUse();
}

void Program::Bind()
{
	glLinkProgram(Id);
	DetachShaders();
}

GLuint Program::GetType() const
{
	return GL_PROGRAM;
}

void Program::Attach(const Shader& shader)
{
	glAttachShader(Id, shader.GetID());
	shaders.emplace_back(shader.GetID());
}


bool Program::GetStatus() const
{
	GLint Result = GL_FALSE;

	glGetProgramiv(Id, GL_LINK_STATUS, &Result);

	return Result == GL_TRUE;
}

const char* Program::GetStatusMessage()
{
	int InfoLength = 0;
	glGetProgramiv(Id, GL_INFO_LOG_LENGTH, &InfoLength);

	if (InfoLength > 0)
	{
		ErrorMsg.resize(static_cast<unsigned int>(InfoLength + 1ULL));
		ErrorMsg[0] = 0;
		glGetProgramInfoLog(Id, InfoLength, NULL, &ErrorMsg[0]);

		return &ErrorMsg[0];
	}

	return "";
}

void Program::DetachShaders()
{
	GLuint id = Id;

	std::for_each(shaders.begin(), shaders.end(), [id](GLuint shader) {
		glDetachShader(id, shader);
	});

	shaders.clear();
}

void Program::Use()
{
	glUseProgram(Id);
}